home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / FunctionList.c < prev    next >
Text File  |  1994-12-03  |  24KB  |  784 lines

  1. /* FunctionList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "FunctionList.h"
  31. #include "StringList.h"
  32. #include "Memory.h"
  33. #include "CodeCenter.h"
  34. #include "Array.h"
  35. #include "FunctionObject.h"
  36. #include "Alert.h"
  37. #include "DataMunging.h"
  38. #include "MainWindowStuff.h"
  39. #include "BufferedFileInput.h"
  40. #include "BufferedFileOutput.h"
  41. #include "Files.h"
  42. #include "Scrap.h"
  43.  
  44.  
  45. struct FunctionListRec
  46.     {
  47.         StringListRec*                    List;
  48.         CodeCenterRec*                    CodeCenter;
  49.         struct MainWindowRec*        MainWindow;
  50.         ArrayRec*                                FunctionArray;
  51.         MyBoolean                                FunctionListChanged;
  52.     };
  53.  
  54.  
  55. #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe FunctionModuleScrap")
  56.  
  57.  
  58. /* create a new function list */
  59. FunctionListRec*        NewFunctionList(struct MainWindowRec* MainWindow,
  60.                                             struct CodeCenterRec* CodeCenter, WinType* ScreenID,
  61.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  62.     {
  63.         FunctionListRec*    FuncList;
  64.  
  65.         FuncList = (FunctionListRec*)AllocPtrCanFail(sizeof(FunctionListRec),
  66.             "FunctionListRec");
  67.         if (FuncList == NIL)
  68.             {
  69.              FailurePoint1:
  70.                 return NIL;
  71.             }
  72.         FuncList->List = NewStringList(ScreenID,XLoc,YLoc,Width,Height,
  73.             GetScreenFont(),9,StringListDontAllowMultipleSelection,"Function Modules");
  74.         if (FuncList->List == NIL)
  75.             {
  76.              FailurePoint2:
  77.                 ReleasePtr((char*)FuncList);
  78.                 goto FailurePoint1;
  79.             }
  80.         FuncList->FunctionArray = NewArray();
  81.         if (FuncList->FunctionArray == NIL)
  82.             {
  83.              FailurePoint3:
  84.                 DisposeStringList(FuncList->List);
  85.                 goto FailurePoint2;
  86.             }
  87.         FuncList->MainWindow = MainWindow;
  88.         FuncList->CodeCenter = CodeCenter;
  89.         FuncList->FunctionListChanged = False;
  90.         return FuncList;
  91.     }
  92.  
  93.  
  94. /* delete the function list and all of the function modules it contains */
  95. void                                DisposeFunctionList(FunctionListRec* FuncList)
  96.     {
  97.         long                            Scan;
  98.         long                            Limit;
  99.  
  100.         CheckPtrExistence(FuncList);
  101.         Limit = ArrayGetLength(FuncList->FunctionArray);
  102.         for (Scan = 0; Scan < Limit; Scan += 1)
  103.             {
  104.                 FunctionObjectRec*    FunctionTemp;
  105.  
  106.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  107.                 DisposeFunctionObject(FunctionTemp);
  108.             }
  109.         DisposeArray(FuncList->FunctionArray);
  110.         DisposeStringList(FuncList->List);
  111.         ReleasePtr((char*)FuncList);
  112.     }
  113.  
  114.  
  115. /* change the location of the function list in the window */
  116. void                                SetFunctionListLocation(FunctionListRec* FuncList,
  117.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  118.     {
  119.         CheckPtrExistence(FuncList);
  120.         SetStringListLoc(FuncList->List,XLoc,YLoc,Width,Height);
  121.     }
  122.  
  123.  
  124. /* redraw the list */
  125. void                                FunctionListRedraw(FunctionListRec* FuncList)
  126.     {
  127.         CheckPtrExistence(FuncList);
  128.         RedrawStringList(FuncList->List);
  129.     }
  130.  
  131.  
  132. /* see if the specified coordinates falls inside the function list rectangle */
  133. MyBoolean                        FunctionListHitTest(FunctionListRec* FuncList,
  134.                                             OrdType XLoc, OrdType YLoc)
  135.     {
  136.         CheckPtrExistence(FuncList);
  137.         return StringListHitTest(FuncList->List,XLoc,YLoc);
  138.     }
  139.  
  140.  
  141. /* handle a mouse down event for the function list */
  142. void                                FunctionListDoMouseDown(FunctionListRec* FuncList, OrdType XLoc,
  143.                                             OrdType YLoc, ModifierFlags Modifiers)
  144.     {
  145.         CheckPtrExistence(FuncList);
  146.         if (StringListMouseDown(FuncList->List,XLoc,YLoc,Modifiers))
  147.             {
  148.                 /* if it returns true, then it was a double click */
  149.                 FunctionListOpenSelection(FuncList);
  150.             }
  151.     }
  152.  
  153.  
  154. /* called when the window becomes active */
  155. void                                FunctionListBecomeActive(FunctionListRec* FuncList)
  156.     {
  157.         CheckPtrExistence(FuncList);
  158.         EnableStringList(FuncList->List);
  159.     }
  160.  
  161.  
  162. /* called when the window becomes inactive */
  163. void                                FunctionListBecomeInactive(FunctionListRec* FuncList)
  164.     {
  165.         CheckPtrExistence(FuncList);
  166.         DisableStringList(FuncList->List);
  167.     }
  168.  
  169.  
  170. /* called when a selection is made in another list, so that this list */
  171. /* is deselected */
  172. void                                FunctionListDeselect(FunctionListRec* FuncList)
  173.     {
  174.         CheckPtrExistence(FuncList);
  175.         DeselectAllStringListElements(FuncList->List);
  176.     }
  177.  
  178.  
  179. /* check to see if there is a selection in this list */
  180. MyBoolean                        FunctionListIsThereSelection(FunctionListRec* FuncList)
  181.     {
  182.         CheckPtrExistence(FuncList);
  183.         return (GetStringListHowManySelectedItems(FuncList->List) > 0);
  184.     }
  185.  
  186.  
  187. /* check to see if any of the function modules contained in this list need */
  188. /* to be saved */
  189. MyBoolean                        DoesFunctionListNeedToBeSaved(FunctionListRec* FuncList)
  190.     {
  191.         long                            Scan;
  192.         long                            Limit;
  193.         MyBoolean                    Flag;
  194.  
  195.         CheckPtrExistence(FuncList);
  196.         Flag = FuncList->FunctionListChanged;
  197.         Limit = ArrayGetLength(FuncList->FunctionArray);
  198.         for (Scan = 0; (Scan < Limit) && !Flag; Scan += 1)
  199.             {
  200.                 FunctionObjectRec*    FunctionTemp;
  201.  
  202.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  203.                 if (HasFunctionObjectBeenModified(FunctionTemp))
  204.                     {
  205.                         Flag = True;
  206.                     }
  207.             }
  208.         return Flag;
  209.     }
  210.  
  211.  
  212. /* open an edit window for the selected function module */
  213. void                                FunctionListOpenSelection(FunctionListRec* FuncList)
  214.     {
  215.         ArrayRec*                    ListOfSelections;
  216.  
  217.         CheckPtrExistence(FuncList);
  218.         ListOfSelections = GetListOfSelectedItems(FuncList->List);
  219.         if (ListOfSelections != NIL)
  220.             {
  221.                 long                            Scan;
  222.                 long                            Limit;
  223.  
  224.                 Limit = ArrayGetLength(ListOfSelections);
  225.                 for (Scan = 0; Scan < Limit; Scan += 1)
  226.                     {
  227.                         FunctionObjectRec*        FunctionTemp;
  228.  
  229.                         FunctionTemp = (FunctionObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  230.                         FunctionObjectOpenWindow(FunctionTemp);
  231.                     }
  232.                 DisposeArray(ListOfSelections);
  233.             }
  234.     }
  235.  
  236.  
  237. /* create a new function module and open a window for it */
  238. void                                FunctionListNewModule(FunctionListRec* FuncList)
  239.     {
  240.         FunctionObjectRec*    Function;
  241.  
  242.         CheckPtrExistence(FuncList);
  243.         /* create the object */
  244.         Function = NewFunctionObject(FuncList->CodeCenter,FuncList->MainWindow,FuncList);
  245.         if (Function == NIL)
  246.             {
  247.              FailurePoint1:
  248.                 AlertHalt("There is not enough memory available to create "
  249.                     "a new function module.",NIL);
  250.                 return;
  251.             }
  252.         /* add it to the string list */
  253.         if (!InsertStringListElement(FuncList->List,NIL,NIL,Function,True))
  254.             {
  255.              FailurePoint2:
  256.                 DisposeFunctionObject(Function);
  257.                 goto FailurePoint1;
  258.             }
  259.         MainWindowDeselectAllOtherStringLists(FuncList->MainWindow,FuncList);
  260.         SelectStringListElement(FuncList->List,Function);
  261.         MakeStringListSelectionVisible(FuncList->List);
  262.         /* add it to the array */
  263.         if (!ArrayAppendElement(FuncList->FunctionArray,Function))
  264.             {
  265.              FailurePoint3:
  266.                 RemoveStringListElement(FuncList->List,Function,True);
  267.                 goto FailurePoint2;
  268.             }
  269.         /* update our internal flags */
  270.         FuncList->FunctionListChanged = True;
  271.         /* change the name in the list */
  272.         FunctionListFunctionNameChanged(FuncList,Function);
  273.         /* show the window */
  274.         FunctionObjectOpenWindow(Function);
  275.     }
  276.  
  277.  
  278. /* delete the selected function module */
  279. void                                FunctionListDeleteSelection(FunctionListRec* FuncList)
  280.     {
  281.         ArrayRec*                    ListOfSelections;
  282.  
  283.         CheckPtrExistence(FuncList);
  284.         ListOfSelections = GetListOfSelectedItems(FuncList->List);
  285.         if (ListOfSelections != NIL)
  286.             {
  287.                 long                                Scan;
  288.                 long                                Limit;
  289.  
  290.                 Limit = ArrayGetLength(ListOfSelections);
  291.                 for (Scan = 0; Scan < Limit; Scan += 1)
  292.                     {
  293.                         FunctionObjectRec*    OneToZap;
  294.  
  295.                         OneToZap = (FunctionObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  296.                         FunctionListDeleteFunction(FuncList,OneToZap);
  297.                     }
  298.                 DisposeArray(ListOfSelections);
  299.             }
  300.     }
  301.  
  302.  
  303. /* delete the explicitly specified function module */
  304. void                                FunctionListDeleteFunction(FunctionListRec* FuncList,
  305.                                             struct FunctionObjectRec* TheFunctionModule)
  306.     {
  307.         long                                Scan;
  308.         long                                Limit;
  309.  
  310.         CheckPtrExistence(FuncList);
  311.         MainWindowClearInstrObjects(FuncList->MainWindow);
  312.         Limit = ArrayGetLength(FuncList->FunctionArray);
  313.         for (Scan = 0; Scan < Limit; Scan += 1)
  314.             {
  315.                 FunctionObjectRec*        FunctionTemp;
  316.  
  317.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  318.                 if (TheFunctionModule == FunctionTemp)
  319.                     {
  320.                         FileSpec*                    BackupFileWhere;
  321.                         FileType*                    BackupFile;
  322.                         MyBoolean                    Success = False;
  323.  
  324.                         BackupFileWhere = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
  325.                             CODE4BYTES('?','?','?','?'));
  326.                         if (BackupFileWhere != NIL)
  327.                             {
  328.                                 if (OpenFile(BackupFileWhere,&BackupFile,eReadAndWrite))
  329.                                     {
  330.                                         BufferedOutputRec*    Output;
  331.  
  332.                                         Output = NewBufferedOutput(BackupFile);
  333.                                         if (Output != NIL)
  334.                                             {
  335.                                                 if (WriteBufferedOutput(Output,sizeof(MAGICSCRAPSTRING),
  336.                                                     MAGICSCRAPSTRING))
  337.                                                     {
  338.                                                         if (FunctionObjectWriteOutData(TheFunctionModule,Output)
  339.                                                             == eFileLoadNoError)
  340.                                                             {
  341.                                                                 Success = True;
  342.                                                             }
  343.                                                     }
  344.                                                 if (!EndBufferedOutput(Output))
  345.                                                     {
  346.                                                         Success = False;
  347.                                                     }
  348.                                             }
  349.                                          else
  350.                                             {
  351.                                                 CloseFile(BackupFile);
  352.                                             }
  353.                                     }
  354.                                  else
  355.                                     {
  356.                                         DeleteFile(BackupFileWhere);
  357.                                         DisposeFileSpec(BackupFileWhere);
  358.                                     }
  359.                             }
  360.                         if (Success)
  361.                             {
  362.                                 MainWindowNewDeleteUndoInfo(FuncList->MainWindow,BackupFileWhere,
  363.                                     BackupFile);
  364.                                 DisposeFunctionObject(FunctionTemp);
  365.                                 RemoveStringListElement(FuncList->List,FunctionTemp,True);
  366.                                 ArrayDeleteElement(FuncList->FunctionArray,Scan);
  367.                                 FuncList->FunctionListChanged = True;
  368.                             }
  369.                          else
  370.                             {
  371.                                 YesNoCancelType        Decision;
  372.  
  373.                                 Decision = AskYesNoCancel("Unable to save undo information for object.  "
  374.                                     "Delete object anyway?",NIL,"Delete","Cancel",NIL/*nothirdbutton*/);
  375.                                 if (Decision == eYes)
  376.                                     {
  377.                                         DisposeFunctionObject(FunctionTemp);
  378.                                         RemoveStringListElement(FuncList->List,FunctionTemp,True);
  379.                                         ArrayDeleteElement(FuncList->FunctionArray,Scan);
  380.                                         FuncList->FunctionListChanged = True;
  381.                                     }
  382.                             }
  383.                         return;
  384.                     }
  385.             }
  386.         EXECUTE(PRERR(AllowResume,"FunctionListDeleteFunction:  couldn't find object"));
  387.     }
  388.  
  389.  
  390. /* the name of a function module has changed, so the name in the scrolling */
  391. /* list must also be changed */
  392. void                                FunctionListFunctionNameChanged(FunctionListRec* FuncList,
  393.                                             struct FunctionObjectRec* TheFunctionModule)
  394.     {
  395.         char*                            FunctionName;
  396.  
  397.         CheckPtrExistence(FuncList);
  398.         CheckPtrExistence(TheFunctionModule);
  399.         ERROR(ArrayFindElement(FuncList->FunctionArray,TheFunctionModule) < 0,
  400.             PRERR(ForceAbort,"FunctionListFunctionNameChanged:  unknown function"));
  401.         FunctionName = FunctionObjectGetNameCopy(TheFunctionModule);
  402.         if (FunctionName != NIL)
  403.             {
  404.                 char*                            FunctionNameNullTerminated;
  405.  
  406.                 FunctionNameNullTerminated = BlockToStringCopy(FunctionName);
  407.                 if (FunctionNameNullTerminated != NIL)
  408.                     {
  409.                         ChangeStringListElementName(FuncList->List,
  410.                             FunctionNameNullTerminated,TheFunctionModule);
  411.                         ReleasePtr(FunctionNameNullTerminated);
  412.                     }
  413.                 ReleasePtr(FunctionName);
  414.             }
  415.     }
  416.  
  417.  
  418. /* remove all object code for all function modules */
  419. void                                FunctionListUnbuildAll(FunctionListRec* FuncList)
  420.     {
  421.         long                            Scan;
  422.         long                            Limit;
  423.  
  424.         CheckPtrExistence(FuncList);
  425.         Limit = ArrayGetLength(FuncList->FunctionArray);
  426.         for (Scan = 0; Scan < Limit; Scan += 1)
  427.             {
  428.                 FunctionObjectRec*    FunctionTemp;
  429.  
  430.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  431.                 FunctionObjectUnbuild(FunctionTemp);
  432.             }
  433.         ERROR(CodeCenterGetNumFunctions(FuncList->CodeCenter) != 0,PRERR(ForceAbort,
  434.             "FunctionListUnbuildAll:  some objects still exist"));
  435.     }
  436.  
  437.  
  438. /* build all functions.  returns True if successful. */
  439. MyBoolean                        FunctionListMakeUpToDate(FunctionListRec* FuncList)
  440.     {
  441.         long                            Scan;
  442.         long                            Limit;
  443.  
  444.         CheckPtrExistence(FuncList);
  445.         Limit = ArrayGetLength(FuncList->FunctionArray);
  446.         for (Scan = 0; Scan < Limit; Scan += 1)
  447.             {
  448.                 FunctionObjectRec*    FunctionTemp;
  449.  
  450.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  451.                 if (!FunctionObjectMakeUpToDate(FunctionTemp))
  452.                     {
  453.                         return False;
  454.                     }
  455.             }
  456.         return True;
  457.     }
  458.  
  459.  
  460. /* the document's name has changed, so update all windows */
  461. void                                FunctionListGlobalNameChange(FunctionListRec* FuncList,
  462.                                             char* NewFilename)
  463.     {
  464.         long                            Scan;
  465.         long                            Limit;
  466.  
  467.         CheckPtrExistence(FuncList);
  468.         Limit = ArrayGetLength(FuncList->FunctionArray);
  469.         for (Scan = 0; Scan < Limit; Scan += 1)
  470.             {
  471.                 FunctionObjectRec*    FunctionTemp;
  472.  
  473.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  474.                 FunctionObjectGlobalNameChange(FunctionTemp,NewFilename);
  475.             }
  476.     }
  477.  
  478.  
  479. /*   4-byte little endian function object count (positive 2s complement) */
  480. /*   n-bytes of data for the function objects */
  481.  
  482.  
  483. /* read function objects from a file.  returns True if completely successful. */
  484. FileLoadingErrors        FunctionListReadData(FunctionListRec* FuncList,
  485.                                             struct BufferedInputRec* Input)
  486.     {
  487.         long                            FunctionObjectCount;
  488.         long                            Scan;
  489.  
  490.         CheckPtrExistence(FuncList);
  491.         CheckPtrExistence(Input);
  492.  
  493.         /*   4-byte little endian function object count */
  494.         if (!ReadBufferedSignedLongLittleEndian(Input,&FunctionObjectCount))
  495.             {
  496.                 return eFileLoadDiskError;
  497.             }
  498.         if (FunctionObjectCount < 0)
  499.             {
  500.                 return eFileLoadBadFormat;
  501.             }
  502.  
  503.         /* read in all of the objects */
  504.         for (Scan = 0; Scan < FunctionObjectCount; Scan += 1)
  505.             {
  506.                 FunctionObjectRec*    FunctionTemp EXECUTE(= (FunctionObjectRec*)0x81818181);
  507.                 FileLoadingErrors        Error;
  508.  
  509.                 /* create the new function object */
  510.                 Error = FunctionObjectNewFromFile(&FunctionTemp,Input,FuncList->CodeCenter,
  511.                     FuncList->MainWindow,FuncList);
  512.                 if (Error != eFileLoadNoError)
  513.                     {
  514.                      FailurePoint1:
  515.                         return Error;
  516.                     }
  517.                 CheckPtrExistence(FunctionTemp);
  518.                 /* add it to the scrolling object list */
  519.                 if (!InsertStringListElement(FuncList->List,NIL,NIL,FunctionTemp,True))
  520.                     {
  521.                      FailurePoint2:
  522.                         DisposeFunctionObject(FunctionTemp);
  523.                         Error = eFileLoadOutOfMemory;
  524.                         goto FailurePoint1;
  525.                     }
  526.                 /* add it to the array */
  527.                 if (!ArrayAppendElement(FuncList->FunctionArray,FunctionTemp))
  528.                     {
  529.                      FailurePoint3:
  530.                         RemoveStringListElement(FuncList->List,FunctionTemp,True);
  531.                         goto FailurePoint2;
  532.                     }
  533.                 /* change the name in the list */
  534.                 FunctionListFunctionNameChanged(FuncList,FunctionTemp);
  535.             }
  536.  
  537.         return eFileLoadNoError;
  538.     }
  539.  
  540.  
  541. /* write function objects to a file.  returns True if completely successful. */
  542. FileLoadingErrors        FunctionListWriteData(FunctionListRec* FuncList,
  543.                                             struct BufferedOutputRec* Output)
  544.     {
  545.         long                            NumObjects;
  546.         long                            Scan;
  547.  
  548.         CheckPtrExistence(FuncList);
  549.         CheckPtrExistence(Output);
  550.  
  551.         /*   4-byte little endian function object count */
  552.         NumObjects = ArrayGetLength(FuncList->FunctionArray);
  553.         if (!WriteBufferedSignedLongLittleEndian(Output,NumObjects))
  554.             {
  555.                 return eFileLoadDiskError;
  556.             }
  557.  
  558.         /* write those little buggers out */
  559.         for (Scan = 0; Scan < NumObjects; Scan += 1)
  560.             {
  561.                 FunctionObjectRec*    FunctionTemp;
  562.                 FileLoadingErrors        Error;
  563.  
  564.                 /* get the thing */
  565.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  566.                 /* write it */
  567.                 Error = FunctionObjectWriteOutData(FunctionTemp,Output);
  568.                 /* handle any bad things */
  569.                 if (Error != eFileLoadNoError)
  570.                     {
  571.                         return Error;
  572.                     }
  573.             }
  574.  
  575.         return eFileLoadNoError;
  576.     }
  577.  
  578.  
  579. /* after a file has been saved, this is called to mark all objects as not modified. */
  580. void                                FunctionListMarkAllObjectsSaved(FunctionListRec* FuncList)
  581.     {
  582.         long                            Scan;
  583.         long                            Limit;
  584.  
  585.         CheckPtrExistence(FuncList);
  586.         Limit = ArrayGetLength(FuncList->FunctionArray);
  587.         for (Scan = 0; Scan < Limit; Scan += 1)
  588.             {
  589.                 FunctionObjectRec*    FunctionTemp;
  590.  
  591.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  592.                 FunctionObjectMarkAsSaved(FunctionTemp);
  593.             }
  594.         FuncList->FunctionListChanged = False;
  595.     }
  596.  
  597.  
  598. /* copy the selected object in the list to the clipboard.  return False if failed. */
  599. MyBoolean                        FunctionListCopyObject(FunctionListRec* FuncList)
  600.     {
  601.         ArrayRec*                            ListOfSelections;
  602.         MyBoolean                            TotalSuccessFlag = False;
  603.  
  604.         CheckPtrExistence(FuncList);
  605.         ListOfSelections = GetListOfSelectedItems(FuncList->List);
  606.         if (ListOfSelections != NIL)
  607.             {
  608.                 if (ArrayGetLength(ListOfSelections) >= 1)
  609.                     {
  610.                         FunctionObjectRec*    FunctionTemp;
  611.                         FileSpec*                        TempFileLocation;
  612.  
  613.                         FunctionTemp = (FunctionObjectRec*)ArrayGetElement(ListOfSelections,0);
  614.                         /* open the temporary file */
  615.                         TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  616.                             CODE4BYTES('\?','\?','\?','\?'));
  617.                         if (TempFileLocation != NIL)
  618.                             {
  619.                                 FileType*                            FileDescriptor;
  620.  
  621.                                 if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  622.                                     {
  623.                                         BufferedOutputRec*        BufferedFile;
  624.  
  625.                                         BufferedFile = NewBufferedOutput(FileDescriptor);
  626.                                         if (BufferedFile != NIL)
  627.                                             {
  628.                                                 MyBoolean                            WriteSucceeded = False;
  629.  
  630.                                                 if (WriteBufferedOutput(BufferedFile,sizeof(MAGICSCRAPSTRING),
  631.                                                     MAGICSCRAPSTRING))
  632.                                                     {
  633.                                                         if (FunctionObjectWriteOutData(FunctionTemp,BufferedFile)
  634.                                                             == eFileLoadNoError)
  635.                                                             {
  636.                                                                 WriteSucceeded = True;
  637.                                                             }
  638.                                                     }
  639.                                                 if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  640.                                                     {
  641.                                                         char*                            Buffer;
  642.                                                         long                            NumberOfBytes;
  643.  
  644.                                                         NumberOfBytes = GetFileLength(FileDescriptor);
  645.                                                         Buffer = AllocPtrCanFail(NumberOfBytes,
  646.                                                             "FunctionListCopyObject:  scrap buffer");
  647.                                                         if (Buffer != NIL)
  648.                                                             {
  649.                                                                 if (SetFilePosition(FileDescriptor,0))
  650.                                                                     {
  651.                                                                         if (0 == ReadFromFile(FileDescriptor,
  652.                                                                             Buffer,NumberOfBytes))
  653.                                                                             {
  654.                                                                                 if (SetScrapToThis(Buffer))
  655.                                                                                     {
  656.                                                                                         TotalSuccessFlag = True;
  657.                                                                                     }
  658.                                                                             }
  659.                                                                     }
  660.                                                                 ReleasePtr(Buffer);
  661.                                                             }
  662.                                                     }
  663.                                             }
  664.                                         CloseFile(FileDescriptor);
  665.                                     }
  666.                                 DeleteFile(TempFileLocation);
  667.                                 DisposeFileSpec(TempFileLocation);
  668.                             }
  669.                     }
  670.                 DisposeArray(ListOfSelections);
  671.             }
  672.         return TotalSuccessFlag;
  673.     }
  674.  
  675.  
  676. /* try to paste the clipboard in as a function object.  returns False if it failed */
  677. /* or the clipboard did not contain a function object. */
  678. MyBoolean                        FunctionListPasteObject(FunctionListRec* FuncList)
  679.     {
  680.         MyBoolean                    TotalSuccessFlag = False;
  681.         char*                            Scrap;
  682.  
  683.         CheckPtrExistence(FuncList);
  684.         Scrap = GetCopyOfScrap();
  685.         if (Scrap != NIL)
  686.             {
  687.                 FileSpec*                    TempFileLocation;
  688.  
  689.                 TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  690.                     CODE4BYTES('\?','\?','\?','\?'));
  691.                 if (TempFileLocation != NIL)
  692.                     {
  693.                         FileType*                            FileDescriptor;
  694.  
  695.                         if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  696.                             {
  697.                                 BufferedOutputRec*        BufferedFile;
  698.  
  699.                                 BufferedFile = NewBufferedOutput(FileDescriptor);
  700.                                 if (BufferedFile != NIL)
  701.                                     {
  702.                                         MyBoolean                            WriteSucceeded = False;
  703.  
  704.                                         if (WriteBufferedOutput(BufferedFile,PtrSize(Scrap),Scrap))
  705.                                             {
  706.                                                 WriteSucceeded = True;
  707.                                             }
  708.                                         if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  709.                                             {
  710.                                                 TotalSuccessFlag = FunctionListPasteFromFile(FuncList,
  711.                                                     FileDescriptor);
  712.                                             }
  713.                                     }
  714.                                 CloseFile(FileDescriptor);
  715.                             }
  716.                         DeleteFile(TempFileLocation);
  717.                         DisposeFileSpec(TempFileLocation);
  718.                     }
  719.                 ReleasePtr(Scrap);
  720.             }
  721.         return TotalSuccessFlag;
  722.     }
  723.  
  724.  
  725. /* try to paste a function object in from a file */
  726. MyBoolean                        FunctionListPasteFromFile(FunctionListRec* FuncList,
  727.                                             struct FileType* File)
  728.     {
  729.         MyBoolean                    TotalSuccessFlag = False;
  730.  
  731.         CheckPtrExistence(FuncList);
  732.         if (SetFilePosition(File,0))
  733.             {
  734.                 BufferedInputRec*    InputFile;
  735.  
  736.                 InputFile = NewBufferedInput(File);
  737.                 if (InputFile != NIL)
  738.                     {
  739.                         char                            HeaderTest[sizeof(MAGICSCRAPSTRING)];
  740.  
  741.                         if (ReadBufferedInput(InputFile,sizeof(MAGICSCRAPSTRING),HeaderTest))
  742.                             {
  743.                                 if (MemEqu(MAGICSCRAPSTRING,HeaderTest,sizeof(MAGICSCRAPSTRING)))
  744.                                     {
  745.                                         FunctionObjectRec*        FunctionTemp EXECUTE(= (FunctionObjectRec*)0x81818181);
  746.  
  747.                                         if (eFileLoadNoError == FunctionObjectNewFromFile(&FunctionTemp,
  748.                                             InputFile,FuncList->CodeCenter,FuncList->MainWindow,FuncList))
  749.                                             {
  750.                                                 CheckPtrExistence(FunctionTemp);
  751.                                                 /* add it to the scrolling object list */
  752.                                                 if (!InsertStringListElement(FuncList->List,NIL,NIL,FunctionTemp,True))
  753.                                                     {
  754.                                                      FailurePoint:
  755.                                                         DisposeFunctionObject(FunctionTemp);
  756.                                                     }
  757.                                                  else
  758.                                                     {
  759.                                                         MainWindowDeselectAllOtherStringLists(FuncList->MainWindow,FuncList);
  760.                                                         SelectStringListElement(FuncList->List,FunctionTemp);
  761.                                                         MakeStringListSelectionVisible(FuncList->List);
  762.                                                         /* add it to the array */
  763.                                                         if (!ArrayAppendElement(FuncList->FunctionArray,FunctionTemp))
  764.                                                             {
  765.                                                                 RemoveStringListElement(FuncList->List,FunctionTemp,True);
  766.                                                                 goto FailurePoint;
  767.                                                             }
  768.                                                          else
  769.                                                             {
  770.                                                                 /* change the name in the list */
  771.                                                                 FunctionListFunctionNameChanged(FuncList,FunctionTemp);
  772.                                                                 TotalSuccessFlag = True;
  773.                                                                 FuncList->FunctionListChanged = True;
  774.                                                             }
  775.                                                     }
  776.                                             }
  777.                                     }
  778.                             }
  779.                         EndBufferedInput(InputFile);
  780.                     }
  781.             }
  782.         return TotalSuccessFlag;
  783.     }
  784.